﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
using MergeTool.ClassLib.Common;
using MergeTool.ClassLib.Configuration;
using Microsoft.Practices.Prism.Commands;

namespace MergeTool.UI.ViewModels
{
    public class LoginViewModel : MyCustomViewModelBase
    {
        public LoginViewModel()
        {
            this.SubmitCommand = new DelegateCommand<object>(this.OnSubmit, this.CanSubmit);
            this._connectionInfoInstance = Settings.GetInstance().ConnectionInfo;
            this._loginDisplayMessage = LoginDisplayMessage;
            this.RemoveUserCommand = new DelegateCommand<object>(RemoveUser);
            this.AddUserCommand = new DelegateCommand<object>(AddUser);
            UserNames = _connectionInfoInstance.UserNames;
            SelectedUserName = _connectionInfoInstance.SelectedUserName;
            NewUserName = _connectionInfoInstance.SelectedUserName;
        }

        private void AddUser(object obj)
        {
            if(!string.IsNullOrEmpty(NewUserName))
                this.UserNames.Add(NewUserName);
        }

        private void RemoveUser(object obj)
        {
            if (!string.IsNullOrEmpty(NewUserName))
            {
                this.UserNames.Remove(NewUserName);
                if (UserNames.Count > 0)
                {
                    NewUserName = UserNames[0];
                    _connectionInfoInstance.SelectedUserName = UserNames[0];
                }
            }
        }

        public DelegateCommand<object> AddUserCommand { get; private set; }

        public DelegateCommand<object> RemoveUserCommand { get; private set; }

        private readonly ConnectionInfo _connectionInfoInstance;

        private async void OnSubmit(object obj)
        {
            this.SubmitCommand.IsActive=true;
            string validateProjectCollection;
            string validateTeamProject;
            string validateUser;
            try
            {
                var connectionResultTask = Task.Run(() => TfsConnection.GetInstance());
                var connectionResult = await connectionResultTask;
                validateProjectCollection = await Task.Run(() => connectionResult.GeTfsTeamProjectCollection().CatalogNode.Resource.DisplayName);
                if (validateProjectCollection != ProjectCollection)
                {
                    throw new Exception("Project collecion is incorrect!");
                }
                validateTeamProject = await Task.Run(() =>connectionResult.GetTeamProject().Name);
                if (validateTeamProject != TeamProject)
                {
                    throw new Exception("Team project is incorrect!");
                }
                validateUser = await Task.Run(() => connectionResult.GetVersionControlServer().AuthorizedIdentity.UniqueName);
                if (validateUser != SelectedUserName)
                {
                    throw new Exception("Username is incorrect!");
                }
                this.ErrorsContainer.ClearErrors("LoginDisplayMessage");
                LoginDisplayMessage = "Successfully authenticated with the server.";
            }
            catch (Exception ex)
            {
                List<ValidationResult> ValidationResults = new List<ValidationResult>();
                LoginDisplayMessage = "Authentication with the server failed, reason: " + ex.Message;
                ValidationResults.Add(new ValidationResult(LoginDisplayMessage));
                this.ErrorsContainer.SetErrors("LoginDisplayMessage", ValidationResults);
                RaiseErrorsChanged("LoginDisplayMessage");
            }
            this.SubmitCommand.IsActive = false;
        }

        private bool CanSubmit(object arg)
        {
            if (string.IsNullOrEmpty(_connectionInfoInstance.TeamProject) || string.IsNullOrEmpty(this.SelectedUserName)
                || string.IsNullOrEmpty(_connectionInfoInstance.ProjectCollection) || string.IsNullOrEmpty(_connectionInfoInstance.TFSUriString))
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        public DelegateCommand<object> SubmitCommand { get; private set; }
        /*
        public string UserName
        {
            get { return this._connectionInfoInstance.UserName; }
            set
            {
                string userName = _connectionInfoInstance.UserName;
                SetProperty(ref userName, value);
                this.SubmitCommand.RaiseCanExecuteChanged();
                _connectionInfoInstance.UserName = value;
            }
        }*/
        private ObservableCollection<string> _userNames;

        public ObservableCollection<string> UserNames
        {
            get
            {
                return this._userNames;
            }
            set
            {
                SetProperty(ref _userNames, value);
            }
        }

        private string _newUserName;

        public string NewUserName
        {
            get { return this._newUserName; }

            set
            {
                SetProperty(ref _newUserName, value);
            }
        }

        private string _selectedUserName;

        public string SelectedUserName
        {
            get { return this._selectedUserName; }
            set
            {
                SetProperty(ref _selectedUserName, value);
                _connectionInfoInstance.SelectedUserName = value;
                this.SubmitCommand.RaiseCanExecuteChanged();
            }
        }

        
        public string TFSUri
        {
            get { return this._connectionInfoInstance.TFSUriString; }
            set
            {
                string tfsUriString = _connectionInfoInstance.TFSUriString;
                SetProperty(ref tfsUriString, value);
                this.SubmitCommand.RaiseCanExecuteChanged();
                _connectionInfoInstance.TFSUriString = value;
            }
        }

        public string ProjectCollection
        {
            get { return this._connectionInfoInstance.ProjectCollection; }
            set
            {
                string projectCollection = _connectionInfoInstance.ProjectCollection;
                SetProperty(ref projectCollection, value);
                this.SubmitCommand.RaiseCanExecuteChanged();
                _connectionInfoInstance.ProjectCollection = value;
            }
        }

        public string TeamProject
        {
            get { return this._connectionInfoInstance.TeamProject; }
            set
            {
                string teamProject = _connectionInfoInstance.TeamProject;
                SetProperty(ref teamProject, value);
                this.SubmitCommand.RaiseCanExecuteChanged();
                _connectionInfoInstance.TeamProject = value;
            }
        }

        private string _loginDisplayMessage;

        public string LoginDisplayMessage
        {
            get { return this._loginDisplayMessage; }
            set
            {
                SetProperty(ref _loginDisplayMessage, value);
            }
        }
    }
}
